package ar.edu.utn.frba.tacs.warnes;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.Test;

import ar.edu.utn.frba.tacs.warnes.pieza.Pieza;
import ar.edu.utn.frba.tacs.warnes.pieza.PiezaReservadaState;
import ar.edu.utn.frba.tacs.warnes.utils.ContenedorWarnes;

public class DBTestCase {
	
	public Session getSession(){
		SessionFactory sessionFactory = null;
		Session session = null;			
		sessionFactory = new AnnotationConfiguration().configure()
		.buildSessionFactory();
		// Abrimos session
		session = sessionFactory.openSession();		
		return session;		
	};
	
	@Test
	public void testPiezasBaseDeDatos() {	
				
		Session session = null;
		Transaction transaction = null;

		try {
			// Levantamos session Factory
			session = getSession();
			transaction = session.beginTransaction();

			Pieza pieza = ContenedorWarnes.getInstance()
					.creaUnaPieza("piezita");

			// Guardo la pieza
			session.save(pieza);

			// COMMITEO LA TRANSACCION
			transaction.commit();

			Query query = session.createQuery("select count(*) from Pieza");
			assertEquals(1, Integer.parseInt(query.list().get(0).toString()));

			query = session.createQuery("select descripcion from Pieza");
			assertEquals("piezita", query.list().get(0).toString());
			
			transaction = session.beginTransaction();

			Pieza pieza2 = ContenedorWarnes.getInstance().creaUnaPieza("piezita");
			session.save(pieza2);

			transaction.commit();

			Query query2 = session.createQuery("select count(*) from Pieza");
			assertEquals(2, Integer.parseInt(query2.list().get(0).toString()));
		}

		catch (Exception e) {
			e.printStackTrace();
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	@Test
	public void testAutosBaseDeDatos() {


		Session session = null;
		Transaction transaction = null;

		try {
			
			// Abrimos session
			session = getSession();
			// Abrimos transaccion manualmente
			transaction = session.beginTransaction();

			Auto auto = ContenedorWarnes.getInstance()
					.creaUnAuto("asd-123");

			// Guardo el auto
			session.save(auto);

			// COMMITEO LA TRANSACCION
			transaction.commit();

			Query query = session.createQuery("select count(*) from Auto");
			assertEquals(1, Integer.parseInt(query.list().get(0).toString()));

			query = session.createQuery("select patente from Auto");
			assertEquals("asd-123", query.list().get(0).toString());
			
			
			transaction = session.beginTransaction();

			Auto auto2 = ContenedorWarnes.getInstance().creaUnAuto("dsa-321");
			session.save(auto2);

			transaction.commit();

			Query query2 = session.createQuery("select count(*) from Auto");
			assertEquals(2, Integer.parseInt(query2.list().get(0).toString()));
		}

		catch (Exception e) {
			e.printStackTrace();
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}
	
	@Test
	public void testVentasBaseDeDatos() {

		Session session = null;
		Transaction transaction = null;

		try {
			// Abrimos session
			session = getSession();
			// Abrimos transaccion manualmente
			transaction = session.beginTransaction();

			Pieza pieza = ContenedorWarnes.getInstance().creaUnaPieza("piezita");
			Pieza pieza2 = ContenedorWarnes.getInstance().creaUnaPieza("piezota");
			List<Pieza> piezas = new ArrayList<Pieza>();
			piezas.add(pieza);piezas.add(pieza2);
			Venta venta = new Venta();
			pieza.cambiarEstado(PiezaReservadaState.getInstance());
			pieza2.cambiarEstado(PiezaReservadaState.getInstance());
			venta.venderPieza(pieza);
			venta.venderPieza(pieza2);
			
			// Guardo la pieza y el pedido
			session.save(pieza);
			session.save(pieza2);
			session.save(venta);

			// COMMITEO LA TRANSACCION
			transaction.commit();

			Query query = session.createQuery("select venta from Pieza");
			assertEquals(venta.getId(),((Venta) query.list().get(0)).getId());
			assertEquals(venta.getId(),((Venta) query.list().get(1)).getId());
			
			Query query2 = session.createQuery("select piezasVendidas from Venta");
			assertEquals(pieza.getId(),((Pieza) query2.list().get(0)).getId());
			assertEquals(pieza2.getId(),((Pieza) query2.list().get(1)).getId());
		}

		catch (Exception e) {
			e.printStackTrace();
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}
	@Test
	public void testReservaBaseDeDatos() {

		Session session = null;
		Transaction transaction = null;

		try {			
			// Abrimos session
			session = getSession();
			// Abrimos transaccion manualmente
			transaction = session.beginTransaction();

			Reserva reserva = ContenedorWarnes.getInstance().nuevaReserva();
			
			session.save(reserva);
			
			Pieza pieza2 = ContenedorWarnes.getInstance().creaUnaPieza("Radio");
			Pieza pieza3 = ContenedorWarnes.getInstance().creaUnaPieza("Parlante");
			
			reserva.reservarPieza(pieza2);
			reserva.reservarPieza(pieza3);
			
			session.save(pieza2);
			session.save(pieza3);
			session.save(reserva);

			// COMMITEO LA TRANSACCION
			transaction.commit();

			Query query = session.createQuery("select count(*) from Reserva");
			assertEquals(1, Integer.parseInt(query.list().get(0).toString()));
			
			query = session.createQuery("select count(*) from Pieza where reserva = " + reserva.getId());
			assertEquals(2, Integer.parseInt(query.list().get(0).toString()));			
			
			query = session.createQuery("select reserva from Pieza");
			assertEquals(reserva.getId(),((Reserva) query.list().get(0)).getId());
			assertEquals(reserva.getId(),((Reserva) query.list().get(1)).getId());
			
			Query query2 = session.createQuery("select piezasReservadas from Reserva");
			assertEquals(pieza2.getId(),((Pieza) query2.list().get(0)).getId());
			assertEquals(pieza3.getId(),((Pieza) query2.list().get(1)).getId());
			
		}

		catch (Exception e) {
			e.printStackTrace();
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

}
